﻿
#
# Author : itech
# 

import os
import re
import Common
from GlobalLogging import GlobalLogging
  
# ====================================================
# perforce operations

class P4Utilities:

    p4itemtypes = {'user':'user', 'group':'group'}
    
    def __init__(self,p4port,p4user,p4passwd = '',p4client = ''):
      self.p4port = p4port
      self.p4user = p4user
      self.p4passwd = p4passwd
      self.p4client = p4client
      os.environ['p4port'] = p4port
      os.environ['p4user'] = p4user
      os.environ['p4passwd'] = p4passwd
      os.environ['p4client'] = p4client
    
    def p4Login(self):
      # if p4password is empty, don't explicitly login, will use your existed ticket
      if self.p4passwd == '' : return True
      
      p4logincmd = str.format('p4 -p %s -c %s -u %s login' % (self.p4port, self.p4client, self.p4user))
      GlobalLogging.getInstance().debug(p4logincmd)
      returncode, stdoutdata, stderrdata = Common.runCommandWithOutput(p4logincmd,self.p4passwd)
      return_value = True 
      if not returncode == 0:
        return_value = False
        GlobalLogging.getInstance().error(repr(stderrdata))
      return return_value
      
    def __getP4Items(self,itemtype):
      itemstype = itemtype + 's'
      p4itemscmd = str.format("p4 %s" % itemstype)
      GlobalLogging.getInstance().debug(p4itemscmd)
      returncode, stdoutdata, stderrdata  = Common.runCommandWithOutput(p4itemscmd)
      if(not returncode == 0):
        GlobalLogging.getInstance().error(repr(stderrdata))
        return None
      
      itemslist = stdoutdata.split("\n")
      itemslist.remove('')
      return itemslist
      
    def p4Users(self):
      return self.__getP4Items(P4Utilities.p4itemtypes['user'])
      
    def p4Groups(self):
     return self.__getP4Items(P4Utilities.p4itemtypes['group'])
      
    def __validateItemIsExisted(self,item, itemtype):
      itemslist = self.__getP4Items(itemtype)
      if itemslist == None:
        return False
      
      if itemtype == 'user':
        for iteminfo in itemslist:
          if iteminfo.startswith(item + ' ') :
            return True
      else:
        for iteminfo in itemslist:
          if iteminfo == item:
            return True
            
      return False
          
    def p4UserIsExisted(self,user):
      return self.__validateItemIsExisted(user,P4Utilities.p4itemtypes['user'])
      
    def p4GroupIsExisted(self,group):
      return self.__validateItemIsExisted(group,P4Utilities.p4itemtypes['group'])
      
    def p4User(self,user,useremail,userfullname):
      p4usercmd = str.format('p4 user -f -o %s' % user)
      GlobalLogging.getInstance().debug(p4usercmd)
      returncode, stdoutdata, stderrdata = Common.runCommandWithOutput(p4usercmd)
      if not returncode == 0 :
        GlobalLogging.getInstance().error(repr(stderrdata))
        return False
      
      userspec = str.format("User: %s\nEmail: %s\nFullName: %s\n" % (user,useremail,userfullname))
      GlobalLogging.getInstance().debug(userspec)
      p4usercmd2 = str.format('p4 user -i -f ')
      GlobalLogging.getInstance().debug(p4usercmd2)
      returncode, stdoutdata, stderrdata = Common.runCommandWithOutput(p4usercmd2,userspec)
      return_value = True 
      if not returncode == 0 :
        return_value = False
        GlobalLogging.getInstance().error(stderrdata) 
      return return_value

    def p4UserIntoGroups(self,user,groups):
      allgroups = groups.split(',')
      for group in allgroups:
        if group == '' : continue
        has = self.p4GroupIsExisted(group)
        if not has : 
          GlobalLogging.getInstance().error(str.format('The group %s is not existed, please create it manually!' % group))
          return False
      
      for group in allgroups:
        p4groupcmd = str.format('p4 group -o %s' % group)
        GlobalLogging.getInstance().debug(p4groupcmd)
        returncode, stdoutdata, stderrdata = Common.runCommandWithOutput(p4groupcmd)
        if not returncode == 0:
          GlobalLogging.getInstance().error(stderrdata)
          return False
          
        regrex = '(.*Users:.*)(Users:.*)'
        r = re.compile(regrex,re.S)
        mo = r.search(stdoutdata)
        if mo == None:
          GlobalLogging.getInstance().error(str.format('Failed to match group %s spec' % group))
          GlobalLogging.getInstance().error(repr(stdoutdata))
          return False
        groupspecnousers = mo.groups()[0]
        users = mo.groups()[1]
        users = users + '        ' + user + '\n'
        groupspec = groupspecnousers + users
        
        p4groupcmd2 = str.format('p4 group -i')
        GlobalLogging.getInstance().debug(p4groupcmd2)
        GlobalLogging.getInstance().debug(groupspec)
        returncode, stdoutdata, stderrdata = Common.runCommandWithOutput(p4groupcmd2,groupspec)
        if not returncode == 0 :
          GlobalLogging.getInstance().error(stderrdata)
          return False

      return True
      
    def p4UserInfo(self,user):
      has = validateUserIsExisted(user)
      if not has :
        GlobalLogging.getInstance().error(str.format('The user %s is not created successfully!' % user))
      else:
        p4usercmd = str.format('p4 user -o %s' % user)
        GlobalLogging.getInstance().debug(p4usercmd )
        returncode, stdoutdata, stderrdata = Common.runCommandWithOutput(p4usercmd)
        if not returncode == 0 :
          GlobalLogging.getInstance().error(repr(stderrdata))
          return ''
        else:
          return stdoutdata

    def p4Sync(self,files):
      p4synccmd = str.format('p4 sync -f %s' % files)
      GlobalLogging.getInstance().debug(p4synccmd)
      returncode, stdoutdata, stderrdata = Common.runCommandWithOutput(p4synccmd)
      if not returncode == 0:
        GlobalLogging.getInstance().error(repr(stderrdata))
        return False
      else:
        return True

    def p4Change(self,description):
      p4changespec = str.format("Change: new\nDescription: %s\n" % description)
      GlobalLogging.getInstance().debug(p4changespec)
      p4changecmd = str.format('p4 change -i')
      GlobalLogging.getInstance().debug('\n' + p4changecmd)
      returncode, stdoutdata, stderrdata = Common.runCommandWithOutput(p4changecmd,p4changespec)
      if not returncode == 0:
        GlobalLogging.getInstance().error(repr(stderrdata))
        return ''
      else:
        return stdoutdata.split()[1]
        
    def p4Edit(self,cl,files,type = ''):
      '''
      type can be text,binary,unicode..., more see perforce File Types.
      files is one string includes all files which are seperated by space or table.
      '''
      p4editcmd = str.format('p4 edit -c %s %s' % (cl,files))
      if not type == '':   p4editcmd = str.format('p4 edit -c %s -t %s %s' % (cl, type, files))  
      GlobalLogging.getInstance().debug(p4editcmd)
      returncode, stdoutdata, stderrdata = Common.runCommandWithOutput(p4editcmd)
      if not returncode == 0:
        GlobalLogging.getInstance().error(repr(stderrdata))
        return False
      else:
        return True
        
    def p4Submit(self,cl):
      p4submitcmd = str.format('p4 submit -c %s' % cl) 
      GlobalLogging.getInstance().debug(p4submitcmd)
      returncode, stdoutdata, stderrdata = Common.runCommandWithOutput(p4submitcmd)
      if not returncode == 0:
        GlobalLogging.getInstance().error(repr(stderrdata))
        return False
      else:
        return True
  
    def p4ClientInfo(self,client):
        p4clientcmd = str.format('p4 client -o %s' % client)
        GlobalLogging.getInstance().debug(p4clientcmd)
        returncode, stdoutdata, stderrdata = Common.runCommandWithOutput(p4clientcmd)
        if not returncode == 0 :
          GlobalLogging.getInstance().error(repr(stderrdata))
          return ''
        else:
          return stdoutdata
          
    def p4LoginAndReturnTicket(self, user):
      p4loginticketcmd = str.format('p4 login -a -p %s ' % user)
      GlobalLogging.getInstance().debug(p4loginticketcmd)
      returncode, stdoutdata, stderrdata = Common.runCommandWithOutput(p4loginticketcmd)
      ticket = repr(stdoutdata)
      ticket = ticket[1:len(ticket)-3]
      return ticket
      
    def p4OpenedFilesByUser(self, user):
      p4OpenedFilescmd = str.format('p4 opened -a -u %s ' % user)
      GlobalLogging.getInstance().debug(p4OpenedFilescmd)
      returncode, stdoutdata, stderrdata = Common.runCommandWithOutput(p4OpenedFilescmd)
      files = stdoutdata
      if not returncode == 0 :
          GlobalLogging.getInstance().error(repr(stderrdata))
          return ''
      else:
          return files
      
    def p4Revert(self,ticket,user,client,host,file):
      p4revertcmd = ''
      if host.strip() == '':
        p4revertcmd = str.format('p4 -p %s -P %s -u %s -c %s revert -k %s' % (self.p4port,ticket,user,client,file))
      else:
        p4revertcmd = str.format('p4 -p %s -P %s -u %s -c %s -H %s revert -k %s' % (self.p4port,ticket,user,client,host,file))
      GlobalLogging.getInstance().debug(p4revertcmd)
      returncode, stdoutdata, stderrdata = Common.runCommandWithOutput(p4revertcmd)
      if not returncode == 0 or not stderrdata == '' :
          GlobalLogging.getInstance().error(repr(stderrdata))
          return ''
      else:
          return stdoutdata
    
    def p4UserRemove(self,user):
      p4userRemovecmd = str.format('p4 user -d -f %s' % user)
      GlobalLogging.getInstance().debug(p4userRemovecmd)
      returncode, stdoutdata, stderrdata = Common.runCommandWithOutput(p4userRemovecmd)
      if not returncode == 0 or not stderrdata == '':
          GlobalLogging.getInstance().error(repr(stderrdata))
          return True
      else:
          GlobalLogging.getInstance().debug(repr(stdoutdata))
          return False
